package com.aaa.system.service.impl;

import com.aaa.system.dao.UserDao;
import com.aaa.system.service.UserService;
import com.aaa.system.vo.PasswordVo;
import com.aaa.system.vo.UserVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.aaa.entity.User;
import com.aaa.utils.JWTUtils;
import com.aaa.utils.WebUtil;
import com.aaa.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author Lei
 * @create 2023-03-20 16:45
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 密码加密器，自定义构建多个用户时，用户的密码必须使用密码加密器进行加密
     */
    @Bean
    private static  PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    public User getByUsername(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",username);
        queryWrapper.eq("status",0);
        User user = userDao.selectOne(queryWrapper);
        //如果找不到当前登录用户，就让它返回null，让代码继续向下执行
        if (Objects.nonNull(user)){
            return user;
        }else {
            return null;
        }
    }

    @Override
    public Result<User> getUserInfo() {
        //获取token
        String token = WebUtil.getRequest().getHeader("token");
        //解析token
        Map<String, Object> info = JWTUtils.getInfo(token);

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",info.get("username"));
        queryWrapper.eq("status",0);
        User user = userDao.selectOne(queryWrapper);
        return new Result<User>(200,"查询用户成功",user);
    }

    @Override
    public Result<IPage<User>> findByCondition(Integer current, Integer size, UserVo userVo) {
        IPage<User> page = new Page<>(current,size);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(userVo.getUserName())){
            queryWrapper.like("user_name",userVo.getUserName());
        }
        if (StringUtils.hasText(userVo.getPhone())){
            queryWrapper.eq("phone",userVo.getPhone());
        }
        if (Objects.nonNull(userVo.getDeptId())){
            queryWrapper.eq("dept_id",userVo.getDeptId());
        }
        if (Objects.nonNull(userVo.getStatus())){
            queryWrapper.eq("status",userVo.getStatus());
        }
        if (Objects.nonNull(userVo.getDateRange()) && userVo.getDateRange().length==2){
            queryWrapper.between("create_time",userVo.getDateRange()[0],userVo.getDateRange()[1]);
        }
        queryWrapper.eq("del_flag","0");

        IPage<User> page1 = userDao.selectPage(page, queryWrapper);
        return new Result<IPage<User>>(200,"查询用户成功",page1);
    }

    @Override
    public Result<Boolean> saveOrUpdateUser(User user) {

        //直接在token获取手机号
        HttpServletRequest request = WebUtil.getRequest();
        String token = request.getHeader("token");
        Map<String, Object> tokenInfo = JWTUtils.getInfo(token);
        String phone = tokenInfo.get("username").toString();
        //通过token获取登录用户信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",phone);
        User userByToken = userDao.selectOne(queryWrapper);
        //将密码加密后再赋值给该用户
        String encode = passwordEncoder().encode(user.getPassword());
        user.setPassword(encode);
        if (Objects.nonNull(user.getUserId())){
            //如果用户id不为空，就是修改用户信息
            user.setUpdateTime(new Date());
            user.setUpdateBy(userByToken.getUserName());
            user.setPassword(encode);
            int i = userDao.updateById(user);
            return new Result<>(200,"修改成功",i>0?true:false);
        }else {
            //如果用户id为空，就是添加用户信息
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            queryWrapper.eq("phone",user.getPhone());
            if (Objects.nonNull(userDao.selectOne(queryWrapper))){
                return new Result<>(500,"该手机号已经被占用");
            }
            user.setCreateTime(new Date());
            user.setCreateBy(userByToken.getUserName());
            user.setPassword(encode);
            int insert = userDao.insert(user);
            return new Result<>(200,"添加成功",insert>0?true:false);
        }
    }

    @Transactional
    @Override
    public Result<Boolean> delUser(Long userId) {
        Boolean b = null;


        //查询要删除用户的信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(userId)){
            queryWrapper.eq("user_id",userId);
        }
        User user1 = userDao.selectOne(queryWrapper);
        //查询当前登录用户的信息
        //直接在token获取手机号
        HttpServletRequest request = WebUtil.getRequest();
        String token = request.getHeader("token");
        Map<String, Object> tokenInfo = JWTUtils.getInfo(token);
        String phone = tokenInfo.get("username").toString();
        //通过token获取登录用户信息
        QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("phone",phone);
        User userByToken = userDao.selectOne(queryWrapper);

        if (user1.getUserId()==userByToken.getUserId()){
            return new Result<>(200,"当前登录角色不能删除",false);
        }else {
            //查询当前用户具有的角色信息
            List<Map<String,String>> userRoleList = userDao.selectRoleList(userId);
            if (userRoleList.size()>0){
                //删除中间表的信息
                userDao.delRoleList(userId);
                b = true;
            }
            User user = new User();
            user.setUserId(userId);
            user.setDelFlag("1");
            int i = userDao.updateById(user);
            return new Result<>(200,"删除成功",i>0?true:false);
        }


    }

    @Transactional
    @Override
    public Result<Boolean> muldelUser(Long[] userIds) {
        for (Long userId : userIds) {
            //查询当前用户具有的角色信息
            List<Map<String,String>> userRoleList = userDao.selectRoleList(userId);
            if (userRoleList.size()>0){
                //删除中间表的信息
                userDao.delRoleList(userId);
            }
        }
        boolean b1 = userDao.muldelUser(userIds);
        return new Result<>(200,"批量删除成功",b1);
    }

    @Override
    public Result<String> checkPhone(String checkphone) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(checkphone)){
            queryWrapper.eq("phone",checkphone);
        }
        User user = userDao.selectOne(queryWrapper);
        if (Objects.nonNull(user)){
            return new Result<>(200,"手机号已存在");
        }else {
            return new Result<>(200,"");
        }
    }

    @Override
    public User getUser() {
        //直接在token获取手机号
        HttpServletRequest request = WebUtil.getRequest();
        String token = request.getHeader("token");
        Map<String, Object> tokenInfo = JWTUtils.getInfo(token);
        String phone = tokenInfo.get("username").toString();
        //通过token获取登录用户信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",phone);
        User user = userDao.selectOne(queryWrapper);
        return user;
    }

    @Override
    public List<User> queryUserNeedScheduling(Map<String, Object> map) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(map.get("userId"))){
            queryWrapper.eq("user_id",map.get("userId"));
        }
        if (Objects.nonNull(map.get("deptId"))){
            queryWrapper.eq("dept_id",map.get("deptId"));
        }
        queryWrapper.eq("del_flag",0);
        queryWrapper.eq("status",0);
        queryWrapper.eq("scheduling_flag","Y");
        List<User> users = userDao.selectList(queryWrapper);
        return users;
    }

    @Override
    public List<User> getListAll() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status",0);
        queryWrapper.eq("del_flag",0);
        List<User> users = userDao.selectList(queryWrapper);
        return users;
    }

    @Override
    public Result<Boolean> revisePassWord(PasswordVo passwordVo) {
        //直接在token获取手机号
        String token = WebUtil.getRequest().getHeader("token");
        Map<String, Object> tokenInfo = JWTUtils.getInfo(token);
        String phone = tokenInfo.get("username").toString();
        //通过手机号获取当前登录用户的信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",phone);
        User user = userDao.selectOne(queryWrapper);
        //数据库加密过的密码
        String password = user.getPassword();

        //将前台传输过来的密码进行加密，然后与数据库密码进行比较
        boolean matches = passwordEncoder().matches(passwordVo.getOldPassword(), password);
        if (matches){
            //如果传过来的密码加密后和数据库密码匹配成功，修改为新密码
            String encode = passwordEncoder().encode(passwordVo.getNewPassword());
            Boolean b = userDao.updateByPhone(phone,encode);
            return new Result<>(200,"修改密码成功",b);
        }
        return new Result<>(200,"旧密码输入错误",false);
    }

    @Override
    public Result<String> quitSystem() {
        //直接在token获取手机号
        HttpServletRequest request = WebUtil.getRequest();
        String token = request.getHeader("token");
        Map<String, Object> tokenInfo = JWTUtils.getInfo(token);
        String phone = tokenInfo.get("username").toString();
        //通过手机号获取当前登录用户的信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",phone);
        User user = userDao.selectOne(queryWrapper);
        //当前用户登录的ip
        String remoteAddr = request.getRemoteAddr();
        user.setLastLoginIp(remoteAddr);
        user.setLastLoginTime(new Date());
        //修改当前登录用户的最后登录时间和登录ip
        int i = userDao.updateById(user);
        //清除redis中的token缓存
        redisTemplate.delete(token);
        return new Result<>(200,"退出成功");
    }

    @Override
    public String getUsernameById(Long userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(userId)){
            queryWrapper.eq("user_id",userId);
        }
        User user = userDao.selectOne(queryWrapper);
        return user.getUserName();
    }

}
